/* eslint-disable no-lonely-if */
/* eslint-disable guard-for-in */
/* eslint-disable max-lines */
/* eslint-disable no-useless-catch */
import { makeAutoObservable } from 'mobx';
import * as api from './api';
import moment from 'moment';
import { t } from '@lingui/macro';
import * as BASE from '@/stores/definitions-base';

const {
  DATETIME_TEXT,
  DATE_TEXT,
  TIME_TEXT,
  EMPTY_TEXT,
  ENUMS: ENUMSBase,
  TitleGrid,
  toSelectDataSource,
} = BASE;
export { DATETIME_TEXT, DATE_TEXT, EMPTY_TEXT, TIME_TEXT, TitleGrid, toSelectDataSource };

export const ENUMS = {
  ...ENUMSBase,
  cities: { begin: {}, end: {} },
  area: { begin: {}, end: {} },
  company: {},
  companySurcharge: {},
  language: {
    1: t`普通话`,
    2: t`粤语`,
    3: t`英语`,
  },
};

export const MAGIC_NUMBERS = {
  // 变更场景
  CHANGE_ORDER_TYPE: {
    // 没有公司
    HAVEORDERID_NOCOMPANYID: '0',
    // 有公司，没有司机
    HAVEORDERID_HAVECOMPANYID_NODRIVERID: '1',
    // 有公司，有司机
    HAVEORDERID_HAVECOMPANYID_HAVEDRIVERID: '2',
  },
  // 司机状态
  DRIVER_STATE: {
    // 取消
    CANCEL: '0',
    // 已派车
    SEND_CAR: '1',
    // 司机已出发
    SET_OFF: '2',
    // 接到乘客 / 开始上客
    PICK_UP: '3',
    // 行程已开始
    START: '4',
    // 行程已结束
    FINISH: '5',
  },
  // 价格类型
  PRICE_TYPE: {
    DIRECT: 0,
    TRANSFER: 1,
  },
  // 公司费用计算规则
  COMPANY_COUNT_TYPE: {
    // 按比例
    ON_RATE: '0',
    // 按金额
    ON_PRICE: '1',
  },
};

class TableArgs {
  constructor(query) {
    this._args = {
      search: {},
      pg: {
        page: 0,
        sort: ['crDate;desc'],
        size: 10,
      },
    };
    this.loading = false;
    this.total = 0;
    this.dataSource = [];
    this.query = query;
    makeAutoObservable(this, {});
  }
  idx(i) {
    return this._args.pg.page * this._args.pg.size + i + 1;
  }

  get pg() {
    return this._args.pg;
  }

  set pg(pg) {
    this.query({ ...pg });
  }

  get search() {
    this._args.pg.page = 0;
    return this._args.search;
  }

  set search(search) {
    this._args.pg.page = 0;
    this._args.search = search;
    this.query({ page: 0 });
  }

  get tableSort() {
    if (this._args.pg.sort?.length) {
      const [fn, dir] = this._args.pg.sort[0].split(';');
      return { [fn]: dir };
    }
    return undefined;
  }
}

export class Calculate {
  _params = {}
  constructor(order, transferLinePrice) {
    this.initParam(order, transferLinePrice);
  }

  initParam(order, transferLinePrice) {
    const ccOrder = order?.ccOrder;
    _.assign(this._params, {
      order,
      sourceCompanyId: '',
      newCompanyId: '',
      newCompanyName: '',
      direction: false,
      companyPrice: '',
    });
    if (!ccOrder.directRoute) {
      this.setParam('order.ccOrder.transferLinePrice', transferLinePrice);
    }
  }

  get param() {
    return this._params;
  }

  setParam(path, value) {
    _.set(this._params, path, value);
  }

  async search() {
    const res = await api.getShareInfo(this._params);
    return res;
  }
}

export class FormData {
  // 用于收集表单数据
  _formData = {};
  // 承运附加费价格
  summarySurchargePrice = [];
  // 变更确认字段数据
  changeInfo = {
    newData: [],
    oldData: [],
  };
  // 收集分账数据
  shareBillInfo = [];

  constructor(data) {
    const {
      order: orderInfo = {},
      task: taskInfo = {},
      initSurchargeInfos: surchargeInfo = [],
      initMerchantSurchargeInfos: merchantSurchargeInfo = [],
      isPreview,
    } = data;
    makeAutoObservable(this, {});
    this._formData = this.createFormData(
      orderInfo,
      taskInfo,
      surchargeInfo,
      merchantSurchargeInfo,
      isPreview,
    );
    this.store = new OrderChangeStore();
    this.shareBillInfo = [];
  }

  get formData() {
    return this._formData;
  }

  set formData(formData) {
    this._formData = formData;
  }

  /**
   * @func 获取表单数据
   * @desc
   * @param {}
   * @return {}
   */
  createFormData(order, task, surchargeArr, merchantSurArr, isPreview) {
    const ccOrder = order?.ccOrder || {};
    const { directRoute } = ccOrder;
    const res = {
      // 乘坐人姓名{string}
      passengerName: ccOrder?.passengerName,
      // 乘坐人电话{string}
      passengerPhone: ccOrder?.passengerPhone,
      // 人数{number}
      number: ccOrder?.number,
      // 预计出发时间{string}
      predictBeginDate: ccOrder?.predictBeginDate,
      // 航班号{string}
      flightNumber: ccOrder?.flightNumber,
      // 开始地区区域{array<string>}
      beginArea: `${ccOrder?.startMainArea}-${ccOrder?.startMinorArea}`,
      // 开始详情地址经纬度{string}
      beginTude: ccOrder?.beginTude,
      // 开始详情地址{string}
      beginName: ccOrder?.beginName,
      // 结束地区区域{array<string>}
      endArea: `${ccOrder?.endMainArea}-${ccOrder?.endMinorArea}`,
      // 结束详情地址经纬度{string}
      endTude: ccOrder?.endTude,
      // 结束详情地址{string}
      endName: ccOrder?.endName,
      // 语言选择{array<number>}
      language: ccOrder?.language,
      // 订单备注{string}
      remarks: ccOrder?.remarks,
      // 订单差价{number}
      priceDifference: ccOrder?.priceDifference || 0,
      // 订单变更备注{string}
      orderChangeRemarks: '',
      // 线路基础价
      basePrice: ccOrder?.rootPrice,

      /* 辅助数据 */
      // 订单数据
      ORDER: order,
      // 任务数据
      TASK: task,
      // 是否只读
      IS_PREVIEW: isPreview,
    };
    // 处理承运信息的表单数据
    if (directRoute) {
      const taskInfo = this.getTaskFormData(order, task, surchargeArr[0], '', merchantSurArr[0]);
      _.assign(res, { taskInfo: [taskInfo] });
    } else {
      const { fromTask, toTask } = task;
      const fromTaskInfo = this.getTaskFormData(order, fromTask, surchargeArr[0], 'from');
      const toTaskInfo = this.getTaskFormData(order, toTask, surchargeArr[1], 'to');
      _.assign(res, { taskInfo: [fromTaskInfo, toTaskInfo] });
    }
    return res;
  }

  /**
   * @func 获取任务表单数据
   * @desc
   * @param {object} order 订单数据
   * @param {object} task 任务数据
   * @param {object} surcharge 附加费对象
   * @return {}
   */
  getTaskFormData(order, task, surcharge, type, merchantSur = {}) {
    const ccOrder = order?.ccOrder || {};
    const vehicleModel = order?.vehicleModel || {};
    const driverUser = order?.driverUser || {};
    const { directRoute } = ccOrder;
    const res = {
      // 任务id
      taskId: task?.id,
      // 公司费用{number}
      carrierPrice: task?.carrierPrice,
      // 公司名称{string}
      companyName: task?.carrierCompanyName,
      // 所属公司id{string}
      companyId: task?.carrierCompany,
      // 承运司机名称{string}
      driver: ccOrder?.driverName,
      // 承运司机id{string}
      driverId: ccOrder?.driverId,
      // 承运车牌
      licenseNo: {
        // 大陆车牌{string}
        mainland: vehicleModel?.licenseNo?.mainland || '',
        // 香港车牌{string}
        hk: vehicleModel?.licenseNo?.hk || '',
      },
      // 承运车辆{string}
      carrierVehicle: vehicleModel?.id,
      // 承运司机电话{string}
      carrierDriverPhone: driverUser?.mobile,
      // 司机费用{number}
      driverServiceFee: task?.driverServiceFee,
      // 任务备注
      taskRemark: task?.remark,
    };
    this.summarySurchargePrice = [];

    const index = type === 'to' ? 1 : 0;
    const orderSur = ccOrder?.surcharges[index];

    const selectKeys = this.initSelectSurchargeKeys(orderSur, merchantSur);

    if (directRoute) {
      _.assign(res, {
        // 附加服务费列表{object}
        surcharges: surcharge,
        // 已选择附加费
        selectedSurchargeKeys: selectKeys.all,
        // 承运商附加费已选key{array<string>}
        selectedSurKeys: selectKeys.sur,
        // 商户已选附加费:{array<string>}
        selectedMerchantSurKeys: selectKeys.merchant,
      });
    } else {
      const driverInfo = this.getDriverInfo(task.driverInfo) || {};
      const [mainland, hk] = driverInfo?.licenseNo?.split('/') || [];
      _.assign(res, {
        // 承运司机名称{string}
        driver: driverInfo?.name,
        // 承运司机id{string}
        driverId: driverInfo?.driverId,
        // 承运车牌
        licenseNo: {
          // 大陆车牌{string}
          mainland,
          // 香港车牌{string}
          hk,
        },
        // 承运车辆{string}
        carrierVehicle: driverInfo?.vehicle,
        // 承运司机电话{string}
        carrierDriverPhone: driverInfo?.phone,
        // 附加服务费列表{object}
        surcharges: surcharge,
        // 已选择所有附加费{array{string}}(用于展示)
        selectedSurchargeKeys: selectKeys.all,
        // 承运商附加费已选key{array<string>}(用于请求参数)
        selectedSurKeys: selectKeys.sur,
        // 商户已选附加费:{array<string>}(用于请求参数)
        selectedMerchantSurKeys: selectKeys.merchant,
      });
    }
    return res;
  }


  /**
   * @func 创建比较对象
   * @desc 用于变更确认展示
   * @param {}
   * @return {}
   */
  createCompareObj(order, task) {
    const [startMainArea, startMinorArea] = order?.beginArea.split('-');
    const [endMainArea, endMinorArea] = order?.endArea.split('-');
    const language = order?.language.reduce((res, cur) => {
      const { language: LANGUAGE } = ENUMS;
      res.push(LANGUAGE[cur]);
      return res;
    }, []).join(',');

    const res = {
      passengerName: order?.passengerName,
      passengerPhone: order?.passengerPhone,
      number: order?.number,
      predictBeginDate: DATETIME_TEXT(order?.predictBeginDate),
      flightNumber: order?.flightNumber || '',
      startMainArea: ENUMS?.cities?.begin[startMainArea],
      startMinorArea: ENUMS?.area?.begin[startMinorArea],
      beginName: order?.beginName,
      endMainArea: ENUMS?.cities?.end[endMainArea],
      endMinorArea: ENUMS?.area?.end[endMinorArea],
      endName: order?.endName,
      predictTime: order?.predictTime,
      priceDifference: order?.priceDifference,
      language,
      orderRemarks: order?.remarks || '',
      companyName: task?.companyName || '',
      surcharges: task?.selectedSurchargeKeys.join(','),
      driverName: task?.driver || '',
      mainland: task?.licenseNo?.mainland || '',
      hk: task?.licenseNo?.hk || '',
      carrierPrice: Number(task?.carrierPrice) || 0,
      driverServiceFee: Number(task?.driverServiceFee) || 0,
      taskRemark: task?.taskRemark || '',
    };
    return res;
  }

  /**
   * @func 获取提交参数
   * @desc
   * @param {}
   * @return {}
   */
  * getParam(originFormData, currFormData) {
    const currTasksInfo = toJS(currFormData?.taskInfo);
    const originTasksInfo = toJS(originFormData?.taskInfo);
    const changeInfo = toJS(this.changeInfo);
    const { ORDER: order, TASK: task } = toJS(originFormData);
    const { directRoute } = order?.ccOrder || {};
    const len = currTasksInfo.length;
    try {
      const {
        id: cursorId,
        transferLinePrice: transferLinePriceTmp,
      } = yield this.store.isRunnerAbleRoad(currFormData);
      const res = [];
      for (let index = 0; index < len; index++) {
        const curTaskInfo = currTasksInfo[index];
        const originParam = this.createParamObj(originFormData, originTasksInfo[index]);
        const currParam = this.createParamObj(currFormData, curTaskInfo);
        const type = this.getAdminChangeOrderType(originParam);
        const differ = this.compareObjects(originParam, currParam);
        const param = this.createParam(differ);
        if (differ.surcharges || differ.predictBeginDate) {
          const surchargesTmp = this.getSurchargeParams(currTasksInfo);
          _.assign(param.otherInfo, { surcharges: surchargesTmp });
        }
        if (differ.language) {
          _.assign(param.otherInfo, { language: currFormData.language });
        }
        changeInfo.newData[index].push(`【订单变更备注】:${currFormData?.orderChangeRemarks}`);

        _.assign(param, {
          type,
          orderId: order?.id,
          taskId: curTaskInfo?.taskId,
          newData: changeInfo.newData[index] || [],
          oldData: changeInfo.oldData[index] || [],
        });
        if (!directRoute) {
          const transferLinePrice = _.cloneDeep(transferLinePriceTmp);
          _.assign(transferLinePrice.fromRoute, {
            companyId: currTasksInfo[0].companyId,
            companyName: currTasksInfo[0].companyName,
          });
          _.assign(transferLinePrice.toRoute, {
            companyId: currTasksInfo[1].companyId,
            companyName: currTasksInfo[1].companyName,
          });
          _.assign(param, { transferLinePrice });
        }
        res.push(param);
      }
      return toJS(res);
    } catch (error) {
      throw (error);
    }
  }

  /**
   * @func 创建参数比较对象
   * @desc
   * @param {}
   * @return {}
   */
  createParamObj(currFormData, taskInfo) {
    const [startMainArea, startMinorArea] = currFormData?.beginArea.split('-');
    const [endMainArea, endMinorArea] = currFormData?.endArea.split('-');

    const res = {
      // 乘坐人姓名{string}
      passengerName: currFormData?.passengerName,
      // 乘坐人电话{string}
      passengerPhone: currFormData?.passengerPhone,
      // 预估开始时间{string}
      predictBeginDate: currFormData?.predictBeginDate,
      // 预估时间
      predictTime: currFormData?.predictTime,
      // 航班号{string}
      flightNumber: currFormData?.flightNumber,
      // 人数{number}
      number: Number(currFormData?.number),
      // 开始城市{string}
      startMainArea,
      // 开始地区{string}
      startMinorArea,
      // 结束城市{string}
      endMainArea,
      // 结束地区{string}
      endMinorArea,
      // 开始详情地址{string}
      beginName: currFormData?.beginName,
      // 结束详情地址{string}
      endName: currFormData?.endName,
      // 开始地址经纬度{string}
      beginTude: currFormData?.beginTude,
      // 结束地址经纬度{string}
      endTude: currFormData?.endTude,
      // 订单差价{number}
      priceDifference: Number(currFormData?.priceDifference) || 0,
      // 语言选择{array<string>}
      language: currFormData?.language,
      // 订单备注{string}
      remarks: currFormData?.remarks,
      // 线路基础价
      rootPrice: currFormData?.basePrice,
      companyId: taskInfo?.companyId,
      companyName: taskInfo?.companyName,
      mainland: taskInfo?.licenseNo.mainland,
      hk: taskInfo?.licenseNo?.hk,
      carrierDriverName: taskInfo?.driver,
      // 承运司机id
      carrierDriver: taskInfo?.driverId,
      // 任务备注
      taskRemark: taskInfo?.taskRemark,
      // 车辆id
      carrierVehicle: taskInfo?.carrierVehicle,
      // 司机电话
      carrierDriverPhone: taskInfo?.carrierDriverPhone,
      // 公司费用
      carrierPrice: Number(taskInfo?.carrierPrice) || 0,
      // 司机费用
      driverServiceFee: Number(taskInfo?.driverServiceFee) || 0,
      // 订单变更备注
      orderChangeRemarks: currFormData?.orderChangeRemarks,
      // 附加费
      surcharges: taskInfo?.selectedSurchargeKeys,
    };
    return res;
  }


  /**
   * @func 创建提交参数对象
   * @desc
   * @param {}
   * @return {}
   */
  createParam(differ) {
    const params = {};
    /* companyInfo */
    const companyInfoTmp = {
      // 公司id
      companyId: differ?.companyId,
      // 公司名称
      companyName: differ?.companyName,
    };
    const companyInfo = JSON.parse(JSON.stringify(companyInfoTmp));
    if (!_.isEmpty(companyInfo)) {
      params.companyInfo = companyInfo;
    }

    /* driverInfo */
    const driverInfoTmp = {
      licenseNo: {
        // 大陆车牌号
        mainland: differ?.mainland,
        // 香港车牌号
        hk: differ?.hk,
      },
      // 司机名
      carrierDriverName: differ?.carrierDriverName,
      // 司机id
      carrierDriver: differ?.carrierDriver,
      // 车辆id
      carrierVehicle: differ?.carrierVehicle,
      // 司机电话
      carrierDriverPhone: differ?.carrierDriverPhone,
    };
    const driverInfo = JSON.parse(JSON.stringify(driverInfoTmp));
    if (_.isEmpty(driverInfo.licenseNo)) {
      delete driverInfo.licenseNo;
    }
    if (!_.isEmpty(driverInfo)) {
      params.driverInfo = driverInfo;
    }

    /* orderInfo */
    const orderInfoTmp = {
      // 乘坐人姓名
      passengerName: differ?.passengerName,
      // 乘坐人电话
      passengerPhone: differ?.passengerPhone,
      // 预估时间
      predictTime: differ?.predictTime,
      // 开始城市
      startMainArea: differ?.startMainArea,
      // 开始地区
      startMinorArea: differ?.startMinorArea,
      // 结束城市
      endMainArea: differ?.endMainArea,
      // 结束地区
      endMinorArea: differ?.endMinorArea,
      // 开始详情地址
      beginName: differ?.beginName,
      // 结束详情地址
      endName: differ?.endName,
      // 开始地址经纬度
      beginTude: differ?.beginTude,
      // 结束地址经纬度
      endTude: differ?.endTude,
      // 航班号
      flightNumber: differ?.flightNumber,
      // 线路基础价
      rootPrice: differ?.rootPrice,
      // 人数
      number: differ?.number,
    };
    if (differ.predictBeginDate) {
      // 预估开始时间
      orderInfoTmp.predictBeginDate = moment(differ?.predictBeginDate).utc().format();
    }

    const orderInfo = JSON.parse(JSON.stringify(orderInfoTmp));
    if (!_.isEmpty(orderInfo)) {
      params.orderInfo = orderInfo;
    }

    /* otherInfo */
    const otherInfoTmp = {
      // 订单备注
      remarks: differ?.remarks,
      // 语言需求
      language: differ?.language,
      // 订单变更备注
      orderChangeRemarks: differ?.orderChangeRemarks || '',
      // 承运价格
      carrierPrice: differ?.carrierPrice,
      // 司机费用
      driverServiceFee: differ?.driverServiceFee,
      // 协议价
      negotiatedPrice: differ?.negotiatedPrice,
      // 订单差价
      priceDifference: differ?.priceDifference,
      // 附加费
      surcharges: differ?.surcharges,
      // 任务备注
      remark: differ?.taskRemark,
    };
    const otherInfo = JSON.parse(JSON.stringify(otherInfoTmp));
    if (!_.isEmpty(otherInfo)) {
      params.otherInfo = otherInfo;
    }
    return JSON.parse(JSON.stringify(params));
  }

  /**
   * @desc 获取对象中的不同项
   * @param {object} originalObj 修改前对象
   * @param {object} modifiedObject 修改后对象
   * @param {string} path 子对象路径(遍历时使用)(初次可不填)
   * @return {object} 对比过后不同值的键值对象
   */
  compareObjects(originalObj, modifiedObj, path = '') {
    // 存储修改的键值对
    const modifiedValues = {};

    for (const key in originalObj) {
      const originalValue = originalObj[key];
      const modifiedValue = modifiedObj[key];

      // 递归处理嵌套的对象和数组
      if (typeof originalValue === 'object' && typeof modifiedValue === 'object') {
        if (moment.isMoment(originalValue) && moment.isMoment(modifiedValue)) {
          // 处理 Moment.js 对象，比较它们的值
          if (!originalValue.isSame(modifiedValue)) {
            const fullPath = path ? `${path}.${key}` : key;
            modifiedValues[fullPath] = modifiedValue;
          }
        } else if (Array.isArray(originalValue) && Array.isArray(modifiedValue)) {
          // 处理数组，仅记录有修改的元素
          const modifiedArray = modifiedValue.reduce((result, item, index) => {
            if (originalValue[index] !== item) {
              result.push(item);
            }
            return result;
          }, []);

          // 如果数组有修改，则记录键值对
          if (modifiedArray.length > 0) {
            const fullPath = path ? `${path}.${key}` : key;
            modifiedValues[fullPath] = modifiedArray;
          } else if (originalValue.length !== modifiedValue.length) {
            const fullPath = path ? `${path}.${key}` : key;
            modifiedValues[fullPath] = modifiedArray;
          }
        } else {
          // 处理其他对象，递归处理
          const nestedPath = path ? `${path}.${key}` : key;
          const nestedModifiedValues = this.compareObjects(originalValue, modifiedValue, nestedPath);

          // 将嵌套对象的修改记录合并到结果中
          Object.assign(modifiedValues, nestedModifiedValues);
        }
      } else {
        // 当属性值不相等时，记录下修改的键值对
        if (originalValue !== modifiedValue) {
          const fullPath = path ? `${path}.${key}` : key;
          modifiedValues[fullPath] = modifiedValue;
        }
      }
    }

    return modifiedValues;
  }

  /**
   * @desc 判断人工介入修改订单api中的type类型
   * @param {}
   * @return {}
   */
  getAdminChangeOrderType(originData) {
    const {
      companyId,
      carrierDriver: driverId,
    } = originData;
    const { CHANGE_ORDER_TYPE } = toJS(MAGIC_NUMBERS);
    if (companyId === null || companyId === undefined || companyId === '') {
      return CHANGE_ORDER_TYPE.HAVEORDERID_NOCOMPANYID;
    } else {
      if (driverId === null || driverId === undefined || driverId === '') {
        return CHANGE_ORDER_TYPE.HAVEORDERID_HAVECOMPANYID_NODRIVERID;
      } else {
        return CHANGE_ORDER_TYPE.HAVEORDERID_HAVECOMPANYID_HAVEDRIVERID;
      }
    }
  }

  /**
   * @func 获取附加费参数
   * @desc
   * @param {}
   * @return {}
   */
  getSurchargeParams(tasksFormData) {
    const [from, to] = tasksFormData;
    const directRoute = tasksFormData.length === 1;
    const res = [];
    if (directRoute) {
      res.push(from.surcharges);
    } else {
      res.push(from.surcharges);
      res.push(to.surcharges);
    }
    return res;
  }

  /**
   * @func 获取有效司机信息
   * @desc
   * @param {}
   * @return {}
   */
  getDriverInfo(driverInfos = []) {
    const { DRIVER_STATE } = MAGIC_NUMBERS;
    if (driverInfos?.length < 0) return {};
    return driverInfos.find((e) => e.state !== DRIVER_STATE.CANCEL) || {};
  }


  /**
   * @func 初始化订单已选择附加费键名
   * @desc
   * @param {}
   * @return {}
   */
  initSelectSurchargeKeys(orderSur, merchantSur = {}) {
    const allSurcharges = _.cloneDeep(orderSur);
    _.assign(allSurcharges, { ...merchantSur });
    let res = {
      // 已选承运商附加费key(用于请求)
      sur: [],
      // 已选商户自定义附加费key(用于请求)
      merchant: [],
      // 所有已选keys(用于展示)
      all: [],
    };
    if (_.isEmpty(allSurcharges)) return res;
    const keys = Object.keys(allSurcharges);
    const merchantKeys = Object.keys(merchantSur);
    if (keys.length <= 0) return res;
    res = keys.reduce((result, key) => {
      const { selectable, checked, accumulation = true } = allSurcharges[key];
      if (selectable) {
        if (checked) {
          if (merchantKeys.includes(key)) {
            result.merchant.push(key);
          } else {
            if (accumulation) {
              result.sur.push(key);
            }
          }
          result.all.push(key);
        }
      } else {
        result.sur.push(key);
        result.all.push(key);
      }
      return result;
    }, res);
    return res;
  }
}

export default class OrderChangeStore {
  options = {
    area: { begin: [], end: [] },
    company: [],
  };

  // 请求返回数据
  apiRes = {
    // 临时订单id
    cursorId: '',
    // 线路基础价
    baseRoadPrice: 0,
    // 换乘站点
    dockingStation: null,
    // 换乘线路信息
    transferLinePrice: {},
    // 线路基础价 新
    totalPrice: 0,
  }

  // 派车数据
  _sendCarArgs = new TableArgs(this.getDriver);

  // 订单变更价
  changedPrice = 0;

  // 订单差价
  priceDifference = 0;
  loading = false;

  // 订单备注信息
  dispatchOrderRemarks = '';


  constructor(rootStore) {
    this.rootStore = rootStore;
    makeAutoObservable(this, { rootStore: false });
  }

  get baseRoadPrice() {
    return this.apiRes.totalPrice;
  }

  set baseRoadPrice(price) {
    this.apiRes.totalPrice = price;
  }


  /**
   * @func 获取当前订单任务数据
   * @param {object} order 订单数据
   * @return {object} 任务数据
   */
  * getTask(order) {
    const { taskIds, id: orderId } = order || {};
    const { directRoute } = order?.ccOrder || {};
    if (directRoute) {
      return yield api.getTaskInfo(taskIds[0]);
    } else {
      return yield api.getTransferTaskInfo(orderId);
    }
  }

  /**
   * @func 获取城市数据
   * @desc 1、返回城市选项数据，2、将选项存储到当前枚举类型中
   * @param {string} fromCity
   * @param {"begin"|"end"} type 获取类型
   * @return {}
   */
  * getCities(fromCity, type) {
    const citiesRes = yield api.getCities(fromCity);
    if (citiesRes.length <= 0) return [];
    const result = citiesRes.reduce((res, cur) => {
      res.options.push({
        label: cur.name,
        value: cur.itemId,
      });

      res.enumData[cur.itemId] = cur.name;
      return res;
    }, { options: [], enumData: {} });

    _.assign(ENUMS.cities, { [type]: result?.enumData });
    _.assign(result?.options, { ...this.options.area[type] });
    this.options.area[type] = toJS(result?.options);
  }

  /**
   * @func 获取区域数据
   * @desc 1.返回区域选项，2、将选项存储到当前枚举类型中
   * @param {string} fromCity
   * @param {string} city
   * @param {"begin"|"end"} type 获取类型
   * @return {}
   */
  * getAreas(fromCity, city, type) {
    const areasRes = yield api.getAreas(fromCity, city);
    if (areasRes.length <= 0) return [];
    const result = areasRes.reduce((res, cur) => {
      res.options.push({
        label: cur.name,
        value: `${city}-${cur.itemId}`,
        isLeaf: true,
      });

      res.enumData[cur.itemId] = cur.name;
      return res;
    }, { options: [], enumData: {} });

    _.assign(ENUMS.area, { [type]: result?.enumData });

    const oldOptions = toJS(this.options.area[type]);
    const options = oldOptions.reduce((res, cur) => {
      if (cur.value === city) {
        cur.children = toJS(result?.options);
      }
      res.push(cur);
      return res;
    }, []);
    _.assign(options, { ...oldOptions });
    this.options.area[type] = toJS(options);
  }

  * getDriver(pgInfo) {
    _.mergeWith(this._args.pg, pgInfo, (o, s) => (_.isArray(o) ? s : undefined)); // 数组直接赋值，不合并
    const { search, pg } = toJS(this._args);
    if (!pg.sort?.length) delete pg.sort;
    this.loading = true;
    try {
      this.total = yield api.countDrivers(search);
      this.dataSource = yield api.getDrivers(search, pg);
    } catch (error) {
      throw (error);
    } finally {
      this.loading = false;
    }
  }

  /**
   * @func 查看当前线路是否可跑
   * @desc
   * @param {}
   * @return {}
   */
  * isRunnerAbleRoad(data) {
    if (_.isEmpty(data)) return;
    const { ORDER: order, TASK: task, ...curFormData } = data;
    const ccOrder = order?.ccOrder || {};
    const merchantId = order?.merchant;
    const [startMainArea, startMinorArea] = curFormData?.beginArea.split('-');
    const [endMainArea, endMinorArea] = curFormData?.endArea.split('-');
    const params = {
      beginName: curFormData.beginName,
      beginTude: curFormData.beginTude,
      endMainArea,
      endMinorArea,
      endName: curFormData.endName,
      endTude: curFormData.endTude,
      orderType: ccOrder?.orderType,
      portType: 0,
      predictBeginDate: moment(curFormData.predictBeginDate).utc().format(),
      startMainArea,
      startMinorArea,
      directRoute: ccOrder?.directRoute,
      orderCrDate: order.crDate,
    };
    if (merchantId) {
      // 整合商户数据参数
      params.merchantId = merchantId;
      params.priceType = 1;
    }
    try {
      const res = yield api.createCursorsOrder(params);
      const { id: cursorId, transferLinePrice } = res;
      // 存储临时订单id
      this.apiRes.cursorId = cursorId;
      // 存储当前换乘信息
      this.apiRes.transferLinePrice = ccOrder?.directRoute ? {} : transferLinePrice;
      return res;
    } catch (error) {
      throw (error?.source?.message);
    }
  }

  /**
   * @func 更新线路基础价
   * @desc
   * 实现：
   * 1、判断当前线路是否可跑（产生临时订单）
   * 2、通过临时订单id查找线路价格
   * 3、获取到线路基础价格，更新值
   * @param {}
   * @return {}
   */
  * updateBaseRoadPrice(data) {
    if (_.isEmpty(data)) return;
    const { PRICE_TYPE } = MAGIC_NUMBERS;
    try {
      yield this.isRunnerAbleRoad(data);
      const { cursorId } = toJS(this.apiRes);
      const { ORDER: order, TASK: task, ...curFormData } = data;
      const { crDate, merchant: merchantId } = order || {};
      const { directRoute } = order?.ccOrder || {};
      const priceType = directRoute ? PRICE_TYPE.DIRECT : PRICE_TYPE.TRANSFER;
      let rootPriceTmp = 0;
      let totalPriceTmp = 0;
      const [from, to] = curFormData?.taskInfo;

      const params = {
        cursorId,
        crDate,
        priceType,
      };

      if (directRoute) {
        const selectedOptions = [...from.selectedSurKeys, ...from.selectedMerchantSurKeys];
        _.assign(params, { fromSelectedOptions: selectedOptions });
      } else {
        const fromSelectedKey = [...from.selectedSurKeys, ...from.selectedMerchantSurKeys];
        const toSelectedKey = [...to.selectedSurKeys, ...to.selectedMerchantSurKeys];

        _.assign(params, {
          fromSelectedOptions: fromSelectedKey,
          toSelectedOptions: toSelectedKey,
        });
      }

      const res = yield api.getCursorsOrderPrice(params, merchantId);
      if (directRoute) {
        if (!res?.rootPrice) {
          throw (t`当前没有直达线路价格`);
        }
        rootPriceTmp = res?.rootPrice?.RMB;
        totalPriceTmp = res?.totalPrice?.RMB;
      } else {
        if (!res?.transferLineRootPrice) {
          throw (t`该线路无法跑通,请重新选择线路`);
        }
        rootPriceTmp = res?.transferLineRootPrice?.RMB;
        totalPriceTmp = res?.transferLineTotalPrice?.RMB;
      }
      const discountTotal = this.countTotalDiscount(order?.discountInfos);
      this.apiRes.baseRoadPrice = rootPriceTmp;
      this.changedPrice = totalPriceTmp - (discountTotal || 0);

      return directRoute ? res?.surcharges : res?.transferLineSurcharges;
    } catch (error) {
      throw (error);
    }
  }

  /**
   * @func 订单变更
   * @desc
   * @param {}
   * @return {}
   */
  * updateOrderChange(data, args) {
    try {
      yield api.update(data, args);
    } catch (error) {
      throw (error);
    }
  }

  /**
   * @func 获取可跑公司
   * @desc
   * @param {}
   * @return {}
   */
  * getCompanies(data) {
    const {
      nonstopSurchargeMap,
      nonstopTaurusSurcharge,
      transferFromSurchargeMap,
      transferToSurchargeMap,
      transferFromTaurusSurcharge,
      transferToTaurusSurcharge,
      companyName,
    } = yield this.isRunnerAbleRoad(data);

    const { ORDER: order, TASK: task, ...curFormData } = data;
    const { directRoute } = order?.ccOrder || {};
    try {
      if (directRoute) {
        const nonstopCompanies = Object.keys(nonstopSurchargeMap);
        if (nonstopCompanies.length <= 0) {
          throw (t`该线路无法跑通,请重新选择线路`);
        }
        ENUMS.company.direct = companyName;
        ENUMS.companySurcharge.direct = nonstopSurchargeMap;
        const options = this.formatCompanyOptions(nonstopSurchargeMap, nonstopTaurusSurcharge, 'direct');
        this.options.company = [{
          type: 'direct',
          dataSource: options,
        }];
      } else {
        const fromCompanies = Object.keys(transferFromSurchargeMap);
        const toCompanies = Object.keys(transferToSurchargeMap);
        if (fromCompanies.length <= 0 || toCompanies.length <= 0) {
          throw (t`该线路无法跑通,请重新选择线路`);
        }
        ENUMS.company.from = companyName;
        ENUMS.companySurcharge.from = transferFromSurchargeMap;
        const optionsFrom = this.formatCompanyOptions(transferFromSurchargeMap, transferFromTaurusSurcharge, 'from');
        ENUMS.company.to = companyName;
        ENUMS.companySurcharge.to = transferToSurchargeMap;
        const optionsTo = this.formatCompanyOptions(transferToSurchargeMap, transferToTaurusSurcharge, 'to');
        this.options.company = [
          {
            type: 'from',
            dataSource: optionsFrom,
          },
          {
            type: 'to',
            dataSource: optionsTo,
          },
        ];
      }
    } catch (error) {
      throw (error);
    }
  }

  /**
   * @func 格式化公司选项数据
   * @desc
   * @param {object} companyObj 可跑公司对象
   * @param {object} priceMap 价格映射对象
   * @param {'direct'|'from'|'to'} type 类型（直达｜A段｜B段）
   * @return {array<object>}
   * 格式：
   * [
   *  {
   *    label: "声波客运公司",
   *    surcharge: {_8座车附加费: {…}, 加急费: {…}, 埃尔法30系附加费: {…}, 举牌: {…}}
   *    value:"CN1014"
   *  },
   * ...
   * ]
   */
  formatCompanyOptions(companiesObj, priceMap, type) {
    const companies = Object.keys(companiesObj);
    let result = { options: [], enums: [] };
    if (companies.length <= 0) return result.options;
    result = companies.reduce((res, companyId) => {
      // 当前公司已有的附加费列表
      const surcharge = companiesObj[companyId] || {};
      const surchargeTmp = {};

      const priceMapKeys = Object.keys(priceMap);
      const companySurchargeKeys = Object.keys(surcharge);
      // 遍历所有公司附加费合集列表
      for (const key of priceMapKeys) {
        const { selectable } = priceMap[key];
        if (!selectable) {
          _.assign(surchargeTmp, { [key]: priceMap[key] });
        }
        if (companySurchargeKeys.includes(key)) {
          _.assign(surchargeTmp, { [key]: priceMap[key] });
        }
      }

      const label = ENUMS.company[type][companyId];
      res.options.push({ value: companyId, label, surcharge: surchargeTmp });
      return res;
    }, { options: [] });

    return result.options;
  }

  /**
   * @func 格式化附加费表格数据
   * @desc
   * @param {}
   * @return {}
   */
  * formatSurchargeTableInfo(surcharges, selectedKey = [], merchantId) {
    let disableSelect = [];
    let merchantSurKeys = [];
    const defaultKey = [...new Set([...selectedKey, ...disableSelect])];
    if (merchantId) {
      const { operatorSurcharges, merchantSurcharges } = yield this.getMerchantInfo(merchantId);
      merchantSurKeys = Object.keys(merchantSurcharges);
      disableSelect = [...operatorSurcharges];
    }


    let res = { tableData: [], defaultKey };
    if (_.isEmpty(surcharges)) return res;
    const surchargeKey = Object.keys(surcharges);
    if (surchargeKey.length <= 0) return res;
    res = surchargeKey.reduce((result, key) => {
      const { HKD, MOP, RMB, checked, selectable } = surcharges[key];
      let disabled = !selectable;
      if (selectable) {
        disabled = disableSelect.includes(key);
      }
      if (!merchantSurKeys.includes(key)) {
        result.tableData.push({
          name: key,
          price: { HKD, MOP, RMB },
          disabled,
        });
      }

      if (selectable) {
        if (checked) {
          if (!selectedKey.includes(key)) {
            result.defaultKey.push(key);
          }
        }
      } else {
        if (!selectedKey.includes(key)) {
          result.defaultKey.push(key);
        }
      }
      return result;
    }, res);
    return res;
  }

  /**
   * @func
   * @desc
   * @param {}
   * @return {}
   */
  * formatNewSurchargeTableInfo(surcharges, selectedKey = [], curTaskFormData, type) {
    const { PRICE_TYPE } = MAGIC_NUMBERS;
    const { cursorId } = toJS(this.apiRes);
    const { ORDER: order, FORM: curFormData } = curTaskFormData;
    const merchantId = order?.merchant;
    const { directRoute } = order?.ccOrder;
    const priceType = directRoute ? PRICE_TYPE.DIRECT : PRICE_TYPE.TRANSFER;

    const paramKeys = selectedKey;

    const data = {
      cursorId,
      priceType,
    };
    if (directRoute) {
      data.nonstopCompanyId = curTaskFormData.companyId;
      const selectKeys = paramKeys;
      data.fromSelectedOptions = selectKeys;
    } else {
      const mergeData = {
        from: {
          fromCompanyId: curTaskFormData.companyId,
          fromSelectedOptions: paramKeys,
          toCompanyId: curFormData.taskInfo[1].companyId,
          toSelectedOptions: curFormData.taskInfo[1].selectedSurchargeKeys,
        },
        to: {
          fromCompanyId: curFormData.taskInfo[0].companyId,
          fromSelectedOptions: curFormData.taskInfo[0].selectedSurchargeKeys,
          toCompanyId: curTaskFormData.companyId,
          toSelectedOptions: paramKeys,
        },
      };
      _.assign(data, mergeData[type]);
    }
    const {
      transferLineTotalPrice,
      totalPrice,
      transferLineSurcharges,
      surcharges: directSurcharges,
    } = yield api.getCursorsOrderPrice(data, merchantId);
    const changedPrice = directRoute ? totalPrice : transferLineTotalPrice;
    const discountTotal = this.countTotalDiscount(order?.discountInfos);
    this.changedPrice = changedPrice.RMB - (discountTotal || 0);

    return directRoute ? directSurcharges : transferLineSurcharges;
  }

  /**
   * @func 初始化附加费数据
   * @desc
   * @param {object} order 当前订单数据
   * @param {array<object>} task 任务数据
   * @return {array<object>} 对应线路公司的附加费列表
   */
  * initSurchargeInfos(order, task) {
    const ccOrder = order?.ccOrder;
    const merchantId = order?.merchant;
    const params = {
      beginName: ccOrder.beginName,
      beginTude: ccOrder.beginTude,
      endMainArea: ccOrder.endMainArea,
      endMinorArea: ccOrder.endMinorArea,
      endName: ccOrder.endName,
      endTude: ccOrder.endTude,
      orderType: ccOrder?.orderType,
      portType: 0,
      predictBeginDate: ccOrder.predictBeginDate,
      startMainArea: ccOrder.startMainArea,
      startMinorArea: ccOrder.startMinorArea,
      directRoute: ccOrder?.directRoute,
      orderCrDate: order.crDate,
    };
    const { totalPrice } = task;
    _.set(this.apiRes, 'totalPrice', totalPrice);
    if (merchantId) {
      // 整合商户数据参数
      params.merchantId = merchantId;
      params.priceType = 1;
    }
    try {
      const {
        nonstopSurchargeMap,
        transferFromSurchargeMap,
        transferToSurchargeMap,
        transferLinePrice,
      } = yield api.createCursorsOrder(params);
      // 参考附加费对象
      const surchargeArr = ccOrder.surcharges;
      if (ccOrder.directRoute) {
        const { carrierCompany } = task;
        const companySurcharge = nonstopSurchargeMap[carrierCompany] || {};
        const res = this.getCurCompanySurcharge(surchargeArr[0], companySurcharge);
        this.apiRes.transferLinePrice = {};
        return [res];
      } else {
        const { fromTask, toTask } = task;
        const fromCompanySurcharge = transferFromSurchargeMap[fromTask.carrierCompany] || {};
        const toCompanySurcharge = transferToSurchargeMap[toTask.carrierCompany] || {};
        const from = this.getCurCompanySurcharge(surchargeArr[0], fromCompanySurcharge);
        const to = this.getCurCompanySurcharge(surchargeArr[1], toCompanySurcharge);
        this.apiRes.transferLinePrice = transferLinePrice;
        return [from, to];
      }
    } catch (error) {
      console.log(error);
    }
  }

  /**
   * @func 获取当前公司附加费
   * @desc 承运商
   * @param {}
   * @return {}
   */
  getCurCompanySurcharge(orderSurcharge, companySurcharge) {
    let res = {};
    // 该订单所有可跑公司附加费key合集
    const orderSurchargeKeys = Object.keys(orderSurcharge);
    if (orderSurchargeKeys.length <= 0) return res;
    // 获取该公司的附加费列表
    const companySurchargeKeys = Object.keys(companySurcharge);
    res = companySurchargeKeys.reduce((result, key) => {
      if (orderSurchargeKeys.includes(key)) {
        const surchargeTmp = _.cloneDeep(orderSurcharge[key]);
        result[key] = surchargeTmp;
      }
      return result;
    }, {});
    return res;
  }

  /**
   * @func 初始化承运商附加费
   * @desc
   * @param {}
   * @return {}
   */
  * initMerchantSurchargeInfos(order, task, merchantId) {
    const { merchantSurcharges: surcharges } = yield this.getMerchantInfo(merchantId);
    const { surcharges: orderSurcharges } = order.ccOrder;
    const res = this.getCurCompanySurcharge(orderSurcharges[0], surcharges);
    return [res];
  }

  /**
   * @func 获取商户信息
   * @desc 获取商户自定义附加费
   * @param {}
   * @return {}
   */
  * getMerchantInfo(merchantId) {
    return yield api.getMerchants(merchantId);
  }

  /**
   * @func 获取请求价格附加费字段参数
   * @desc
   * @param {}
   * @return {}
   */
  getSelectedOptionsParam(allSelectKeys, excludeKeys) {
    const paramKeys = allSelectKeys.reduce((res, key) => {
      if (!excludeKeys.includes(key)) {
        res.push(key);
      }
      return res;
    }, []);
    return paramKeys;
  }

  /**
   * @func
   * @desc
   * @param {}
   * @return {}
   */
  * updateCompanyPrice(curFormData, task, index) {
    if (_.isEmpty(curFormData)) return;
    const { beginArea = '', endArea = '', ORDER: order } = curFormData;
    const ccOrder = order?.ccOrder;
    const [startMainArea, startMinorArea] = beginArea?.split('-');
    const [endMainArea, endMinorArea] = endArea?.split('-');


    const params = {
      companyId: task?.companyId,
      startMainArea,
      startMinorArea,
      endMainArea,
      endMinorArea,
      priceType: '1',
      portType: ccOrder?.portType,
    };

    const { dockingStation } = this.apiRes?.transferLinePrice || {};
    if (dockingStation) {
      const { mainArea, minorArea } = yield this.getDockingStationInfo(dockingStation);
      if (index === 0) {
        params.endMainArea = mainArea;
        params.endMinorArea = minorArea;
      } else {
        params.startMainArea = mainArea;
        params.startMinorArea = minorArea;
      }
    }
    const { specificSingleFare } = yield api.getCompanyPrice(params);
    const carrierPrice = specificSingleFare?.RMB || 0;

    let key = 'direct';
    let predictBeginDate = curFormData?.predictBeginDate;
    if (!ccOrder?.directRoute) {
      key = index === 0 ? 'from' : 'to';
      const { fromRoute } = toJS(this.apiRes.transferLinePrice);
      predictBeginDate = index === 0 ? predictBeginDate : moment(predictBeginDate)?.add(fromRoute?.predictTime, 'hours');
    }
    const surcharge = ENUMS.companySurcharge[key][task.companyId] || {};

    const gCPArgs = {
      orderSurcharge: toJS(task?.surcharges),
      companySurcharge: surcharge,
      predictBeginDate: moment(predictBeginDate)?.utc().format(),
    };
    const surCompanyPrice = yield api.getSurCompanyPriceTotal(gCPArgs);

    const res = carrierPrice + surCompanyPrice;
    return res;
  }

  * getDockingStationInfo(dockingStation) {
    const res = yield api.getDictIdItemId('region', dockingStation);
    const { fullId } = res;
    const cityId = fullId.split(':')[0];
    return { mainArea: cityId, minorArea: dockingStation };
  }

  /**
   * @func 计算总折扣
   * @desc
   * @param {}
   * @return {}
   */
  countTotalDiscount(discountInfos) {
    if (discountInfos?.length <= 0) return 0;
    const res = discountInfos?.reduce((sum, cur) => {
      const { discountPrice = 0 } = cur;
      return sum + discountPrice;
    }, 0);
    return res;
  }
}
